package com.lswms.modules.lswms.service.impl.recipient;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lswms.common.constant.Constant;
import com.lswms.common.page.PageData;
import com.lswms.common.service.impl.CrudServiceImpl;
import com.lswms.common.utils.ConvertUtils;
import com.lswms.modules.lswms.Constant.RecipientConstant;
import com.lswms.modules.lswms.Constant.TaskConstant;
import com.lswms.modules.lswms.Constant.TradeConstant;
import com.lswms.modules.lswms.dao.base.LocationDao;
import com.lswms.modules.lswms.dao.base.SkuDao;
import com.lswms.modules.lswms.dao.recipient.RecipientsDao;
import com.lswms.modules.lswms.dao.recipient.RecipientsinfoDao;
import com.lswms.modules.lswms.dao.stock.InventoryDao;
import com.lswms.modules.lswms.dao.stock.LotDao;
import com.lswms.modules.lswms.dao.stock.TradeDao;
import com.lswms.modules.lswms.dao.task.TaskDao;
import com.lswms.modules.lswms.dao.uniquecode.UniquecodeDao;
import com.lswms.modules.lswms.dao.uniquecode.UniquecoderecordDao;
import com.lswms.modules.lswms.dto.recipient.RecipientsDTO;
import com.lswms.modules.lswms.entity.base.LocationEntity;
import com.lswms.modules.lswms.entity.base.SkuEntity;
import com.lswms.modules.lswms.entity.receipt.ReceiptEntity;
import com.lswms.modules.lswms.entity.recipient.RecipientsEntity;
import com.lswms.modules.lswms.entity.recipient.RecipientsinfoEntity;
import com.lswms.modules.lswms.entity.stock.InventoryEntity;
import com.lswms.modules.lswms.entity.stock.LotEntity;
import com.lswms.modules.lswms.entity.stock.TradeEntity;
import com.lswms.modules.lswms.entity.task.TaskEntity;
import com.lswms.modules.lswms.entity.uniquecode.UniquecodeEntity;
import com.lswms.modules.lswms.entity.uniquecode.UniquecoderecordEntity;
import com.lswms.modules.lswms.service.base.SequenceService;
import com.lswms.modules.lswms.service.receipt.ReceiptdetaillistService;
import com.lswms.modules.lswms.service.recipient.RecipientsService;
import com.lswms.modules.security.user.SecurityUser;

/**
 * ${comments}
 *
 * @author DX sunlightcs@gmail.com
 * @since 1.0.0 2021-07-19
 */
@Service
public class RecipientsServiceImpl extends CrudServiceImpl<RecipientsDao, RecipientsEntity, RecipientsDTO>
		implements RecipientsService {

	@Autowired
	InventoryDao inventoryDao;

	@Autowired
	TaskDao taskDao;

	@Autowired
	SequenceService sequenceService;

	@Autowired
	RecipientsinfoDao recipientsinfoDao;

	@Autowired
	TradeDao tradeDao;

	@Autowired
	LotDao lotDao;

	@Autowired
	SkuDao skuDao;

	@Autowired
	LocationDao locationDao;

	@Autowired
	ReceiptdetaillistService receiptdetaillistService;

	@Autowired
	private UniquecodeDao uniquecodeDao;

	@Autowired
	private UniquecoderecordDao uniquecoderecordDao;

	@Override
	public QueryWrapper<RecipientsEntity> getWrapper(Map<String, Object> params) {
		String id = (String) params.get("id");
		String cardid = (String) params.get("cardid");
		String recipient = (String) params.get("recipient");
		String sku = (String) params.get("sku");
		String descr = (String) params.get("descr");

		String status = (String) params.get("status");
		String recipientkey = (String) params.get("recipientkey");

		String recipienttype = (String) params.get("recipienttype");
		String lot7 = (String) params.get("lot7");
		String recipientid = (String) params.get("recipientid");

		QueryWrapper<RecipientsEntity> wrapper = new QueryWrapper<>();
		wrapper.eq(StringUtils.isNotBlank(id), "a.id", id);
		wrapper.eq(StringUtils.isNotBlank(cardid), "a.cardid", cardid);
		wrapper.eq(StringUtils.isNotBlank(recipient), "a.recipient", recipient);
		wrapper.eq(StringUtils.isNotBlank(sku), "a.sku", sku);
		wrapper.like(StringUtils.isNotBlank(descr), "e.descr", descr);
		wrapper.eq(StringUtils.isNotBlank(status), "a.status", status);
		wrapper.eq(StringUtils.isNotBlank(recipienttype), "a.recipienttype", recipienttype);
		wrapper.eq(StringUtils.isNotBlank(recipientkey), "a.recipientkey", recipientkey);
		wrapper.eq(StringUtils.isNotBlank(lot7), "f.lot7", lot7);
		wrapper.eq(StringUtils.isNotBlank(recipientid), "a.recipientid", recipientid);

		wrapper.orderByDesc("a.recipientkey");
		return wrapper;
	}

	@Override
	public PageData<RecipientsEntity> pageBySql(HttpServletRequest request) throws ParseException {

		Map<String, Object> param = new HashMap<String, Object>();
		param.put(Constant.PAGE, request.getParameter(Constant.PAGE));
		param.put(Constant.LIMIT, request.getParameter(Constant.LIMIT));
		param.put(Constant.ORDER_FIELD, request.getParameter(Constant.ORDER_FIELD));
		param.put(Constant.ORDER, request.getParameter(Constant.ORDER));

//		String id = request.getParameter("id");
//		String receiptkey = request.getParameter("receiptkey");
//		String type = request.getParameter("type");
//		String status = request.getParameter("status");
//		String sourcekey = request.getParameter("sourcekey");
//		String supplierkey = request.getParameter("companyid");
//		String suppliername = request.getParameter("companyname");
//		String[] addtime = request.getParameterValues("addtime");

		String id = request.getParameter("id");
		String cardid = request.getParameter("cardid");
		String recipient = request.getParameter("recipient");
		String sku = request.getParameter("sku");
		String descr = request.getParameter("descr");
		String factorycdoe = request.getParameter("factorycdoe");

		String status = request.getParameter("status");
		String recipientkey = request.getParameter("recipientkey");

		String recipienttype = request.getParameter("recipienttype");
		String lot7 = request.getParameter("lot7");
		String recipientid = request.getParameter("recipientid");
		String recipienttime[] = request.getParameterValues("recipienttime");
		
		String sort = request.getParameter("sort");

		String[] sorts = null;
		String type = null;
		if (StringUtils.isNotBlank(sort)) {
			sorts = sort.split("#");
		}
		if(sorts!=null){
			type = sorts.length>0 ? sorts[sorts.length-1] : null;
		}


		QueryWrapper<RecipientsEntity> wrapper = new QueryWrapper<>();
		wrapper.eq(StringUtils.isNotBlank(id), "a.id", id);
		wrapper.eq(StringUtils.isNotBlank(cardid), "a.cardid", cardid);
		wrapper.eq(StringUtils.isNotBlank(recipient), "a.recipient", recipient);
		wrapper.eq(StringUtils.isNotBlank(sku), "a.sku", sku);
		wrapper.like(StringUtils.isNotBlank(descr), "e.descr", descr);
		wrapper.like(StringUtils.isNotBlank(factorycdoe), "e.factorycdoe", factorycdoe);
		wrapper.eq(StringUtils.isNotBlank(status), "a.status", status);
		wrapper.eq(StringUtils.isNotBlank(recipienttype), "a.recipienttype", recipienttype);
		wrapper.eq(StringUtils.isNotBlank(recipientkey), "a.recipientkey", recipientkey);
		wrapper.eq(StringUtils.isNotBlank(lot7), "f.lot7", lot7);
		wrapper.eq(StringUtils.isNotBlank(recipientid), "a.recipientid", recipientid);
		
		//wrapper.in(sorts != null && sorts.length > 0, "e.sort", sorts);
		wrapper.likeRight(StringUtils.isNotBlank(type),"e.sort",type);
		
		if (null != recipienttime && recipienttime.length==2  ) {
			if(StringUtils.isNotBlank(recipienttime[0]) && StringUtils.isNotBlank(recipienttime[1])) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Date date = sdf.parse(recipienttime[0].replace('T', ' '));
			Date date2 = sdf.parse(recipienttime[1].replace('T', ' '));

			Calendar calendar = new GregorianCalendar();
			calendar.setTime(date);
			calendar.add(calendar.DATE, 1); // 把日期往后增加一天,整数 往后推,负数往前移动
			date = calendar.getTime();
			
			Calendar calendar2 = new GregorianCalendar();
			calendar2.setTime(date2);
			calendar2.add(calendar2.DATE, 2); // 把日期往后增加两天,整数 往后推,负数往前移动
			date2 = calendar2.getTime();
			wrapper.between("a.recipienttime", date, date2);
			}
		}

//		QueryWrapper<RecipientsEntity> wrapper = new QueryWrapper<>();
//		wrapper.eq(StringUtils.isNotBlank(id), "id", id);
//		wrapper.eq(StringUtils.isNotBlank(receiptkey), "receiptkey", receiptkey);
//		wrapper.eq(StringUtils.isNotBlank(type), "type", type);
//		wrapper.eq(StringUtils.isNotBlank(status), "status", status);
//		wrapper.eq(StringUtils.isNotBlank(sourcekey), "sourcekey", sourcekey);
//		wrapper.eq(StringUtils.isNotBlank(supplierkey), "companyid", supplierkey);
//		wrapper.eq(StringUtils.isNotBlank(suppliername), "companyname", suppliername);
//		if (null != addtime) {
//			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//			Date date = sdf.parse(addtime[0].replace('T', ' '));
//			Date date2 = sdf.parse(addtime[1].replace('T', ' '));
//
//			Calendar calendar = new GregorianCalendar();
//			calendar.setTime(date2);
//			calendar.add(calendar.DATE, 1); // 把日期往后增加一天,整数 往后推,负数往前移动
//			date2 = calendar.getTime();
//			wrapper.between("addtime", date, date2);
//		}

		wrapper.orderByDesc("a.recipientkey");

		IPage<RecipientsEntity> page = baseDao.selectPageBySql(getPage(param, null, false), wrapper);
		return getPageData(page, RecipientsEntity.class);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public String save1(RecipientsDTO dto) {
		String cardId = dto.getCardid();
		String recipientId = dto.getRecipientid();
		String recipient = dto.getRecipient();
		String sku = dto.getSku();
		BigDecimal qty = dto.getQty();

		if (StringUtils.isBlank(cardId)) {
			return "领用人卡号不能为空";
		}
//		if (StringUtils.isBlank(recipientId)) {
//			return "领用人ID不能为空";
//		}
		if (StringUtils.isBlank(recipient)) {
			return "领用人不能为空";
		}
		if (StringUtils.isBlank(sku)) {
			return "物料编码不能为空";
		}
		if (qty.compareTo(BigDecimal.ZERO) <= 0) {
			return "数量必须为大于0的整数";
		}

		String lot = dto.getLot();
		String location = dto.getFromloc();
		String tray = dto.getFromtray();
		String box = dto.getFrombox();
		if (StringUtils.isNotBlank(lot) && StringUtils.isNotBlank(location) && StringUtils.isNotBlank(tray)
				&& StringUtils.isNotBlank(box)) {
			// 校验库存信息
			QueryWrapper<InventoryEntity> inventoryQuery = new QueryWrapper<InventoryEntity>();
			inventoryQuery.eq("sku", sku);
			inventoryQuery.eq("lot", lot);
			inventoryQuery.eq("location", location);
			inventoryQuery.eq("tray", tray);
			inventoryQuery.eq("box", box);

			InventoryEntity inventoryEntity = inventoryDao.selectOne(inventoryQuery);
			if (inventoryEntity == null) {
				return "选择的库存不存在,请重新选择";
			}
			BigDecimal qtyInventory = inventoryEntity.getQty();
			BigDecimal pickqtyInventory = inventoryEntity.getPickqty();
			BigDecimal availableQty = qtyInventory.subtract(pickqtyInventory);
			if (qtyInventory.compareTo(BigDecimal.ZERO) <= 0) {
				return "选择的库存量是" + qtyInventory + ",无法使用,请重新选择";
			}
			if (qty.compareTo(availableQty) > 0) {
				return "选择的库存量是" + availableQty + ",小于需求数量" + qty + ",请重新选择";
			}

//			BigDecimal pickQty = inventoryEntity.getPickqty();
//			BigDecimal putQty = inventoryEntity.getPutqty();
//			if (pickQty.compareTo(BigDecimal.ZERO) > 0 || putQty.compareTo(BigDecimal.ZERO) > 0) {
//				return "选择的库存已被使用,请重新选择";
//			}
			// 查询是否存在未完成的任务
			QueryWrapper<TaskEntity> TaskQuery = new QueryWrapper<TaskEntity>();
			TaskQuery.lt("status", TaskConstant.TASK_9);
			TaskQuery.and(wrapper -> wrapper.eq("fromtray", tray).or().eq("totray", tray));
			Integer count = taskDao.selectCount(TaskQuery);
			if (count > 0) {
				return "选择的库存已被使用,请重新选择";
			}
		}

		// 如果是立体库位,校验堆垛机是否可用
		QueryWrapper<LocationEntity> queryLocation = new QueryWrapper<LocationEntity>();
		queryLocation.eq("location", dto.getLoc());
		queryLocation
				.exists(" select  1 from WCS_DDJ where lswms_location.lane = WCS_DDJ.DVC_NO and WCS_DDJ.status <>'1' ");

		Integer count1 = locationDao.selectCount(queryLocation);
		if (count1 == 1) {
			return "选择的库位的堆垛机已停用，无法出库";
		}

		// 查询领用人的领取上限
		QueryWrapper<RecipientsinfoEntity> queryRecipients = new QueryWrapper<RecipientsinfoEntity>();
		queryRecipients.eq("cardId", cardId);
		RecipientsinfoEntity recipientsinfoEntity = recipientsinfoDao.selectOne(queryRecipients);

		if (recipientsinfoEntity == null) {
			return "领用人卡号不存在，请重新录入";
		}

		String recipienttype = dto.getRecipienttype();
		if (recipienttype.equals("BORROW")) {
			BigDecimal recipientscount = recipientsinfoEntity.getRecipientscount();
			// 查询已经借用量
			BigDecimal hastcount = baseDao.selectHasCount(cardId);
			if (hastcount != null && recipientscount.compareTo(hastcount.add(qty)) < 0) {
				return "已超过最大允许借用数量，不能继续借用";
			}
		}

		RecipientsEntity recipientsEntity = new RecipientsEntity();

		recipientsEntity.setCardid(cardId);
		recipientsEntity.setRecipientid(recipientId);
		recipientsEntity.setRecipient(recipient);
		recipientsEntity.setRecipienttype(dto.getRecipienttype());
		recipientsEntity.setPriority(dto.getPriority());
		recipientsEntity.setStatus(dto.getStatus());
		recipientsEntity.setSku(sku);
		recipientsEntity.setPreqty(qty);
		recipientsEntity.setQty(qty);
		recipientsEntity.setLot(lot);

		recipientsEntity.setFromloc(location);
		recipientsEntity.setFromtray(tray);
		recipientsEntity.setFrombox(box);

		recipientsEntity.setLoc(location);
		recipientsEntity.setTray(tray);
		recipientsEntity.setBox(box);

		recipientsEntity.setToloc("PY");
		recipientsEntity.setTotray(tray);
		recipientsEntity.setTobox(box);

		recipientsEntity.setStatus(RecipientConstant.RECIPIENT_STATUS_0);

		baseDao.insert(recipientsEntity);

		if (StringUtils.isNotBlank(lot) && StringUtils.isNotBlank(location) && StringUtils.isNotBlank(tray)
				&& StringUtils.isNotBlank(box)) {

			// 选中库存后，设置拣货量
			QueryWrapper<InventoryEntity> inventoryQuery = new QueryWrapper<InventoryEntity>();
			inventoryQuery.eq("sku", sku);
			inventoryQuery.eq("lot", lot);
			inventoryQuery.eq("location", location);
			inventoryQuery.eq("tray", tray);
			inventoryQuery.eq("box", box);
			InventoryEntity inventoryEntity = inventoryDao.selectOne(inventoryQuery);

			InventoryEntity inventoryUpdate = new InventoryEntity();
			inventoryUpdate.setPickqty(inventoryEntity.getPickqty().add(qty));

			UpdateWrapper<InventoryEntity> inventoryUpdateWrapper = new UpdateWrapper<InventoryEntity>();
			inventoryUpdateWrapper.eq("sku", sku);
			inventoryUpdateWrapper.eq("lot", lot);
			inventoryUpdateWrapper.eq("location", location);
			inventoryUpdateWrapper.eq("tray", tray);
			inventoryUpdateWrapper.eq("box", box);
			inventoryDao.update(inventoryUpdate, inventoryUpdateWrapper);
		}

		return null;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public String valideAndUpdate(RecipientsDTO dto) {
		String cardId = dto.getCardid();
		String recipientId = dto.getRecipientid();
		String recipient = dto.getRecipient();
		String sku = dto.getSku();
		BigDecimal qty = dto.getQty();

		if (StringUtils.isBlank(cardId)) {
			return "领用人卡号不能为空";
		}
//		if (StringUtils.isBlank(recipientId)) {
//			return "领用人ID不能为空";
//		}
		if (StringUtils.isBlank(recipient)) {
			return "领用人不能为空";
		}
		if (StringUtils.isBlank(sku)) {
			return "物料编码不能为空";
		}
		if (qty.compareTo(BigDecimal.ZERO) <= 0) {
			return "数量必须为大于0的整数";
		}

		String lot = dto.getLot();
		String location = dto.getLoc();
		String tray = dto.getTray();
		String box = dto.getBox();

		// 先删除原有的记录
		QueryWrapper<RecipientsEntity> recipientsQueryPre = new QueryWrapper<RecipientsEntity>();
		recipientsQueryPre.eq("recipientkey", dto.getRecipientkey());
		RecipientsEntity recipientsEntityPre = baseDao.selectOne(recipientsQueryPre);
		String lotPre = recipientsEntityPre.getLot();
		String locationPre = recipientsEntityPre.getLoc();
		String trayPre = recipientsEntityPre.getTray();
		String boxPre = recipientsEntityPre.getBox();
		BigDecimal qtyPre = recipientsEntityPre.getQty();

		if (qtyPre.compareTo(BigDecimal.ZERO) > 0) {
			QueryWrapper<InventoryEntity> queryInventory = new QueryWrapper<InventoryEntity>();
			queryInventory.eq("lot", lotPre);
			queryInventory.eq("location", locationPre);
			queryInventory.eq("tray", trayPre);
			queryInventory.eq("box", boxPre);
			InventoryEntity inventoryEntity = inventoryDao.selectOne(queryInventory);
			BigDecimal pickQty = inventoryEntity.getPickqty();
			if (pickQty.compareTo(qtyPre) < 0) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return "箱号：" + tray + "格号：" + box + "批号：" + lot + "的分配量不足，处理失败";
			}

			UpdateWrapper<InventoryEntity> UpdateInventory = new UpdateWrapper<InventoryEntity>();
			UpdateInventory.eq("lot", lotPre);
			UpdateInventory.eq("location", locationPre);
			UpdateInventory.eq("tray", trayPre);
			UpdateInventory.eq("box", boxPre);

			InventoryEntity inventoryEntityUpdate = new InventoryEntity();
			inventoryEntityUpdate.setPickqty(pickQty.subtract(qtyPre));

			inventoryDao.update(inventoryEntityUpdate, UpdateInventory);

			UpdateWrapper<RecipientsEntity> updateWrapperRecipients = new UpdateWrapper<RecipientsEntity>();
			updateWrapperRecipients.eq("recipientkey", dto.getRecipientkey());

			RecipientsEntity UpdateRecipientsEntity = new RecipientsEntity();

			UpdateRecipientsEntity.setRecipienttype(StringUtils.EMPTY);
			UpdateRecipientsEntity.setPriority(0);
			UpdateRecipientsEntity.setStatus(RecipientConstant.RECIPIENT_STATUS_0);
			UpdateRecipientsEntity.setSku(StringUtils.EMPTY);
			UpdateRecipientsEntity.setPreqty(BigDecimal.ZERO);
			UpdateRecipientsEntity.setQty(BigDecimal.ZERO);
			UpdateRecipientsEntity.setLot(StringUtils.EMPTY);
			UpdateRecipientsEntity.setFromloc(StringUtils.EMPTY);
			UpdateRecipientsEntity.setFromtray(StringUtils.EMPTY);
			UpdateRecipientsEntity.setFrombox(StringUtils.EMPTY);
			UpdateRecipientsEntity.setLoc(StringUtils.EMPTY);
			UpdateRecipientsEntity.setTray(StringUtils.EMPTY);
			UpdateRecipientsEntity.setBox(StringUtils.EMPTY);
			UpdateRecipientsEntity.setToloc(StringUtils.EMPTY);
			UpdateRecipientsEntity.setTotray(StringUtils.EMPTY);
			UpdateRecipientsEntity.setTobox(StringUtils.EMPTY);

			baseDao.update(UpdateRecipientsEntity, updateWrapperRecipients);

		}

		if (StringUtils.isNotBlank(lot) && StringUtils.isNotBlank(location) && StringUtils.isNotBlank(tray)
				&& StringUtils.isNotBlank(box)) {
			// 校验库存信息
			QueryWrapper<InventoryEntity> inventoryQuery = new QueryWrapper<InventoryEntity>();
			inventoryQuery.eq("sku", sku);
			inventoryQuery.eq("lot", lot);
			inventoryQuery.eq("location", location);
			inventoryQuery.eq("tray", tray);
			inventoryQuery.eq("box", box);

			InventoryEntity inventoryEntity = inventoryDao.selectOne(inventoryQuery);
			if (inventoryEntity == null) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return "选择的库存不存在,请重新选择";
			}
			BigDecimal qtyInventory = inventoryEntity.getQty();
			BigDecimal pickqtyInventory = inventoryEntity.getPickqty();
			if (qty.compareTo(qtyInventory.subtract(pickqtyInventory)) > 0) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return "选择的库存量是" + qtyInventory + ",小于需求数量" + qty + ",请重新选择";
			}

//			BigDecimal pickQty = inventoryEntity.getPickqty();
//			BigDecimal putQty = inventoryEntity.getPutqty();
//			if (pickQty.compareTo(BigDecimal.ZERO) > 0 || putQty.compareTo(BigDecimal.ZERO) > 0) {
//				return "选择的库存已被使用,请重新选择";
//			}
			// 查询是否存在未完成的任务
			QueryWrapper<TaskEntity> TaskQuery = new QueryWrapper<TaskEntity>();
			TaskQuery.lt("status", TaskConstant.TASK_9);
			TaskQuery.and(wrapper -> wrapper.eq("fromtray", tray).or().eq("totray", tray));
			Integer count = taskDao.selectCount(TaskQuery);
			if (count > 0) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return "选择的库存已被使用,请重新选择";
			}
		}

		// 查询领用人的领取上限
		QueryWrapper<RecipientsinfoEntity> queryRecipients = new QueryWrapper<RecipientsinfoEntity>();
		queryRecipients.eq("cardId", cardId);
		RecipientsinfoEntity recipientsinfoEntity = recipientsinfoDao.selectOne(queryRecipients);
		BigDecimal recipientscount = recipientsinfoEntity.getRecipientscount();

		// 查询已经借用量
		BigDecimal hastcount = baseDao.selectHasCount(cardId);
		if (hastcount != null && recipientscount.compareTo(hastcount.add(qty)) < 0) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return "已超过最大允许借用数量，不能继续借用";
		}

		RecipientsEntity recipientsEntity = new RecipientsEntity();

//		recipientsEntity.setCardid(cardId);
//		recipientsEntity.setRecipientid(recipientId);
//		recipientsEntity.setRecipient(recipient);
		recipientsEntity.setRecipienttype(dto.getRecipienttype());
		recipientsEntity.setPriority(dto.getPriority());
		recipientsEntity.setStatus(dto.getStatus());
		recipientsEntity.setSku(sku);
		recipientsEntity.setPreqty(dto.getStatus() == 7 ? dto.getQty() : qty);
		recipientsEntity.setQty(qty);
		recipientsEntity.setLot(lot);

		recipientsEntity.setFromloc(dto.getStatus() == 7 ? dto.getFromloc() : location);
		recipientsEntity.setFromtray(dto.getStatus() == 7 ? dto.getFromtray() : tray);
		recipientsEntity.setFrombox(dto.getStatus() == 7 ? dto.getFrombox() : box);

		recipientsEntity.setLoc(location);
		recipientsEntity.setTray(tray);
		recipientsEntity.setBox(box);

		recipientsEntity.setToloc("PY");
		recipientsEntity.setTotray(tray);
		recipientsEntity.setTobox(box);

//		recipientsEntity.setStatus(RecipientConstant.RECIPIENT_STATUS_0);

		UpdateWrapper<RecipientsEntity> updateWrapperRecipients = new UpdateWrapper<RecipientsEntity>();
		updateWrapperRecipients.eq("recipientkey", dto.getRecipientkey());

		baseDao.update(recipientsEntity, updateWrapperRecipients);

		if (StringUtils.isNotBlank(lot) && StringUtils.isNotBlank(location) && StringUtils.isNotBlank(tray)
				&& StringUtils.isNotBlank(box)) {

			// 选中库存后，设置拣货量
			QueryWrapper<InventoryEntity> inventoryQuery = new QueryWrapper<InventoryEntity>();
			inventoryQuery.eq("sku", sku);
			inventoryQuery.eq("lot", lot);
			inventoryQuery.eq("location", location);
			inventoryQuery.eq("tray", tray);
			inventoryQuery.eq("box", box);
			InventoryEntity inventoryEntity = inventoryDao.selectOne(inventoryQuery);

			InventoryEntity inventoryUpdate = new InventoryEntity();
			inventoryUpdate.setPickqty(inventoryEntity.getPickqty().add(qty));

			UpdateWrapper<InventoryEntity> inventoryUpdateWrapper = new UpdateWrapper<InventoryEntity>();
			inventoryUpdateWrapper.eq("sku", sku);
			inventoryUpdateWrapper.eq("lot", lot);
			inventoryUpdateWrapper.eq("location", location);
			inventoryUpdateWrapper.eq("tray", tray);
			inventoryUpdateWrapper.eq("box", box);
			inventoryDao.update(inventoryUpdate, inventoryUpdateWrapper);
		}

		return null;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public String release(List<RecipientsEntity> recipientsList, String remoteAddr) {
		for (RecipientsEntity RecipientsEntity : recipientsList) {

			String msg = release(RecipientsEntity, remoteAddr);

			if (msg != null) {

				// 回滚事务
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return msg;

			}
		}

		return null;
	}

	private String release(RecipientsEntity recipientsEntity, String remoteAddr) {
		// 查询领用记录
		QueryWrapper<RecipientsEntity> query = new QueryWrapper<RecipientsEntity>();
		query.eq("recipientkey", recipientsEntity.getRecipientkey());

		RecipientsEntity recipientsEntity1 = baseDao.selectOne(query);

		String loc = recipientsEntity1.getLoc();
		String tray = recipientsEntity1.getTray();
		String box = recipientsEntity1.getBox();
		BigDecimal qty = recipientsEntity1.getQty();

		if (StringUtils.isBlank(loc) || StringUtils.isBlank(tray) || StringUtils.isBlank(box)
				|| qty.compareTo(BigDecimal.ZERO) <= 0) {
			return "领用号：" + recipientsEntity.getRecipientkey() + "未选择有效库存，请选择";
		}

		Integer status = recipientsEntity1.getStatus();
		if (status >= RecipientConstant.RECIPIENT_STATUS_3) {
			return "领用号：" + recipientsEntity.getRecipientkey() + "已发放";
		}

		// 查询库位属性
		QueryWrapper<LocationEntity> queryLocation = new QueryWrapper<LocationEntity>();
		queryLocation.eq("location", loc);
		LocationEntity locationEntity = locationDao.selectOne(queryLocation);
		String isCreate = locationEntity.getIscreate();
		if (StringUtils.isNotBlank(isCreate) && isCreate.equals("1")) {
			// 生成任务
			TaskEntity taskEntity = new TaskEntity();
			String taskkey = sequenceService.getSequence("task");

			taskEntity.setTaskkey(taskkey);
			taskEntity.setTasktype(TaskConstant.TASK_PY);
			taskEntity.setPriority(0);
			taskEntity.setStatus(TaskConstant.TASK_0);
			taskEntity.setSourcekey(recipientsEntity1.getRecipientkey().toString());
			taskEntity.setSourceline(null);
			taskEntity.setSourcelinelist(null);
			taskEntity.setSku(recipientsEntity1.getSku());
			taskEntity.setQty(recipientsEntity1.getQty());
			taskEntity.setFromlocation(recipientsEntity1.getLoc());
			taskEntity.setTolocation(recipientsEntity1.getToloc());
			taskEntity.setFromtray(recipientsEntity1.getTray());
			taskEntity.setTotray(recipientsEntity1.getTotray());
			taskEntity.setFrombox(recipientsEntity1.getBox());
			taskEntity.setTobox(recipientsEntity1.getTobox());
			taskEntity.setFromlot(recipientsEntity1.getLot());
			taskEntity.setTolot(recipientsEntity1.getLot());
			taskEntity.setRemark("");
			taskEntity.setIp(remoteAddr);
			taskDao.insert(taskEntity);
		}
		// 更新状态
		UpdateWrapper<RecipientsEntity> recipientsUpdate = new UpdateWrapper<RecipientsEntity>();
		recipientsUpdate.eq("recipientkey", recipientsEntity1.getRecipientkey());
		recipientsUpdate.set("status", RecipientConstant.RECIPIENT_STATUS_3);
		baseDao.update(null, recipientsUpdate);

		return null;
	}

	@Override
	public List<RecipientsEntity> getByTray(String tray) {
		QueryWrapper<RecipientsEntity> queryWrapper = new QueryWrapper<RecipientsEntity>();
		queryWrapper.eq("lswms_recipients.tray", tray);
		queryWrapper.le("lswms_recipients.status", RecipientConstant.RECIPIENT_STATUS_7);

		queryWrapper.orderByAsc("lswms_recipients.sku");
		return baseDao.selectListBySql(queryWrapper);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public String savePicklist(List<RecipientsEntity> list) {
		// 若目的托盘和原托盘一样，则拣货数量要和箱数量一样
		// 如果不一致，则要更换新的托盘

		// 验证数量的有效性
		if (list.size() == 0) {
			return "不存在分拣录";
		}
		String tray = "";
		Map<String, BigDecimal> map = new HashMap<String, BigDecimal>();
		for (RecipientsEntity recipientsEntity : list) {
			BigDecimal qty = recipientsEntity.getQty();
			String box = recipientsEntity.getBox();
			String lot = recipientsEntity.getLot();
			tray = recipientsEntity.getTray();
			if (qty.compareTo(BigDecimal.ZERO) < 0) {
				return "数量不能为负数";
			}

			String key = lot + "#" + box;
			if (map.containsKey(key)) {
				map.put(key, map.get(key).add(qty));
			} else {
				map.put(key, qty);
			}
		}

		// 拣选后的数量与库存数量进行对比
		QueryWrapper<InventoryEntity> inventoryQuery = new QueryWrapper<InventoryEntity>();
		inventoryQuery.eq("tray", tray);
		inventoryQuery.gt("qty", 0);
		List<InventoryEntity> inventoryList = inventoryDao.selectList(inventoryQuery);
		for (InventoryEntity inventoryEntity : inventoryList) {
			BigDecimal qty = inventoryEntity.getQty();
			String lot = inventoryEntity.getLot();
			String box = inventoryEntity.getBox();

			String key = lot + "#" + box;
			if (map.containsKey(key)) {
				map.put(key, map.get(key).subtract(qty));
			} else {
				map.put(key, qty.negate());
			}
		}

		// 原托盘有剩余量，就需要分拣到新的托盘
		boolean mustChangeTray = false;
		for (BigDecimal qty : map.values()) {
			if (qty.compareTo(BigDecimal.ZERO) > 0) {
				return "库存不足，分拣失败";
			}
			if (qty.compareTo(BigDecimal.ZERO) < 0) {
				mustChangeTray = true;
			}
		}

		for (RecipientsEntity recipientsEntity : list) {
			// 填写的量
			BigDecimal qty = recipientsEntity.getQty();
			tray = recipientsEntity.getTray();
			String toTray = recipientsEntity.getTotray();
			String box = recipientsEntity.getBox();
			String toBox = recipientsEntity.getTobox();
			String sku = recipientsEntity.getSku();
			Integer recipientkey = recipientsEntity.getRecipientkey();
			String uniquecodes = recipientsEntity.getUniquecodes();
			String isuniquecode = recipientsEntity.getIsuniquecode();
//			if (qty.compareTo(BigDecimal.ZERO) < 0) {
//				return "数量不能为负数";
//			}

			// 查询当前行的记录
			QueryWrapper<RecipientsEntity> queryWrapper = new QueryWrapper<RecipientsEntity>();
			queryWrapper.eq("recipientkey", recipientkey);

			RecipientsEntity recipientsEntityEntityPre = baseDao.selectOne(queryWrapper);
			// 修改前的实际量
			BigDecimal qtyPre = recipientsEntityEntityPre.getQty();
			String lot = recipientsEntityEntityPre.getLot();
			String loc = recipientsEntityEntityPre.getLoc();
			Integer status = recipientsEntityEntityPre.getStatus();
			// 已拣货的明细不能在拣货
			if (status >= 5) {
				continue;
			}

			// 提示需要更换托盘
			if (mustChangeTray && tray.equals(toTray)) {
				// 回滚事务
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return "请使用新的箱号";
			}

			// 校验有未完成的任务就不允许校验========================================================
			if (tray != "" && tray != null) {
				QueryWrapper<Integer> wrapper = new QueryWrapper<>();
				wrapper.eq("fromtray", tray);
				wrapper.notIn("status", 9);
				Integer task_tary = taskDao.getTaskTaryCount(wrapper);
				if (task_tary != 0) {
					return "该箱存在未完成的任务，不能进行分拣！";
				}
			}
			// 如果是原数量且原tray，不允许换box
//			if (!mustChangeTray && tray.equals(toTray) && !box.equals(toBox)) {
//				// 回滚事务
//				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//				return "箱号被改变，请还原";
//			}

			// 更换新的箱号后， 新箱号是否空闲，或新箱号只存PY货位有拣货记录，存放的是相同物料
			if (qtyPre.compareTo(qty) != 0 && tray.equals(toTray)) {
				// 查询新箱号的库存记录
				QueryWrapper<InventoryEntity> inventoryQueryTotray = new QueryWrapper<InventoryEntity>();
				inventoryQueryTotray.eq("tray", tray);
				inventoryQueryTotray.gt("qty", 0);

				List<InventoryEntity> inventoryListTotray = inventoryDao.selectList(inventoryQueryTotray);

				for (InventoryEntity inventoryEntity : inventoryListTotray) {
					String inventorylocation = inventoryEntity.getLocation();
					if (!inventorylocation.equals("PY")) {
						// 回滚事务
						TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
						return "填写的箱号的库存不在PY库位，不允许参与分拣使用";
					}

//					String inventoryBox = inventoryEntity.getBox();
//					String inventorySku = inventoryEntity.getSku();
//					if (toBox.equals(inventoryBox) && !sku.equals(inventorySku)) {
//						// 回滚事务
//						TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//						return "填写的格号已存有其他物料,请更换箱号";
//					}
				}
			}

			if (StringUtils.isNotBlank(isuniquecode) && isuniquecode.equals("1")) {
				if (StringUtils.isBlank(uniquecodes)) {
					return "部分唯一码不存在";
				}
				String[] split = uniquecodes.split("\n");
				for (String item : split) {
					Integer integer = uniquecodeDao.checkUniquecode(item);
					if (integer == 0) {
						TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
						return "部分唯一码不存在";
					}
				}
				for (String item : split) {
					UniquecodeEntity uniquecodeEntity = uniquecodeDao.getListByUniquecode(item);
					String checkTray = uniquecodeEntity.getTray();
					String checkBox = uniquecodeEntity.getBox();
					if (!(checkBox.equals(box) && checkTray.equals(tray))) {
						TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
						return "该箱位没有对应的唯一码";
					}
				}

				if (qty.compareTo(new BigDecimal(split.length)) != 0) {
					return "箱：" + tray + " 格" + box + "分拣的数量和唯一码数量不一致";
				}

				for (String item : split) {

					UniquecoderecordEntity uniquecoderecordEntity = new UniquecoderecordEntity();

					UniquecodeEntity uniquecodeET = uniquecodeDao.getListByUniquecode(item);

					uniquecoderecordEntity.setUniquecode(uniquecodeET.getUniquecode());
					uniquecoderecordEntity.setFromtray(uniquecodeET.getTray());
					uniquecoderecordEntity.setFrombox(uniquecodeET.getBox());
					uniquecoderecordEntity.setSku(uniquecodeET.getSku());
					uniquecoderecordEntity.setLot(uniquecodeET.getLot());

					uniquecodeET.setTray(toTray);
					uniquecodeET.setBox(toBox);

					uniquecoderecordEntity.setTotray(toTray);
					uniquecoderecordEntity.setTobox(toBox);
					uniquecoderecordEntity.setSourcetype(TradeConstant.TRADETYPE_MV);
					uniquecoderecordEntity.setSourcetable("recipients");
					uniquecoderecordEntity.setSourceid(recipientsEntity.getId());
					uniquecoderecordEntity.setSourcekey(recipientsEntity.getRecipientkey().toString());
					uniquecoderecordEntity.setSourceline(null);
					uniquecoderecordEntity.setSourcelinelist(null);

					uniquecodeDao.updateById(uniquecodeET);
					uniquecoderecordDao.insert(uniquecoderecordEntity);
				}
			}

			// 原始托盘和箱号的记录qty减去实际的拣货量 、pickqty 减去原有的拣货量
			// 查询库存记录
			QueryWrapper<InventoryEntity> inventoryQuery2 = new QueryWrapper<InventoryEntity>();
			inventoryQuery2.eq("lot", lot);
			inventoryQuery2.eq("location", loc);
			inventoryQuery2.eq("tray", tray);
			inventoryQuery2.eq("box", box);
			InventoryEntity inventoryEntity = inventoryDao.selectOne(inventoryQuery2);

			// 对原托盘箱号库存记录做变更
			UpdateWrapper<InventoryEntity> inventoryUpdate = new UpdateWrapper<InventoryEntity>();
			inventoryUpdate.eq("lot", lot);
			inventoryUpdate.eq("location", loc);
			inventoryUpdate.eq("tray", tray);
			inventoryUpdate.eq("box", box);

			inventoryUpdate.set("qty", inventoryEntity.getQty().subtract(qty));
			inventoryUpdate.set("pickqty", inventoryEntity.getPickqty().subtract(qtyPre));
			inventoryDao.update(null, inventoryUpdate);

			// 对目的托盘箱号的库存记录做变更，若存在库存，更新记录，不存则新增记录
			QueryWrapper<InventoryEntity> inventoryToQuery = new QueryWrapper<InventoryEntity>();
			inventoryToQuery.eq("lot", lot);
			inventoryToQuery.eq("location", loc);
			inventoryToQuery.eq("tray", toTray);
			inventoryToQuery.eq("box", toBox);
			InventoryEntity inventorytoEntity = inventoryDao.selectOne(inventoryToQuery);
			if (inventorytoEntity != null) {
				UpdateWrapper<InventoryEntity> inventoryToUpdate = new UpdateWrapper<InventoryEntity>();
				inventoryToUpdate.eq("lot", lot);
				inventoryToUpdate.eq("location", loc);
				inventoryToUpdate.eq("tray", toTray);
				inventoryToUpdate.eq("box", toBox);
				inventoryToUpdate.set("qty", inventorytoEntity.getQty().add(qty));
				inventoryToUpdate.set("pickqty", inventorytoEntity.getPickqty().add(qty));
				inventoryDao.update(null, inventoryToUpdate);
			} else {
				InventoryEntity inventoryInsert = new InventoryEntity();
				inventoryInsert.setLot(lot);
				inventoryInsert.setSku(sku);
				inventoryInsert.setLocation(loc);
				inventoryInsert.setTray(toTray);
				inventoryInsert.setBox(toBox);
				inventoryInsert.setQty(qty);
				inventoryInsert.setPickqty(qty);
				inventoryInsert.setPutqty(BigDecimal.ZERO);
				inventoryInsert.setStatus(0);
				inventoryDao.insert(inventoryInsert);
			}
			// 新增trade记录
			if (qtyPre.compareTo(qty) != 0 || !tray.equals(toTray) || !box.equals(toBox)) {
				// 增加交易信息
				String tradekey = sequenceService.getSequence("trade");
				TradeEntity tradeEntity = new TradeEntity();

				tradeEntity.setTradekey(tradekey);
				tradeEntity.setTradetype(TradeConstant.TRADETYPE_MV);
				tradeEntity.setSku(sku);
				tradeEntity.setQty(qty);
				tradeEntity.setSourcetype(TradeConstant.SOURCETYPE_MOVE);
				tradeEntity.setSourcekey(null);
				tradeEntity.setSourceline(null);
				tradeEntity.setSourcelinelist(null);
				tradeEntity.setFromlocation(loc);
				tradeEntity.setTolocation(loc);
				tradeEntity.setFromtray(tray);
				tradeEntity.setTotray(toTray);
				tradeEntity.setFrombox(box);
				tradeEntity.setTobox(toBox);
				tradeEntity.setFromlot(lot);
				tradeEntity.setTolot(lot);
				tradeEntity.setFromlot1(null);
				tradeEntity.setFromlot2(null);
				tradeEntity.setFromlot3("");
				tradeEntity.setFromlot4("");
				tradeEntity.setFromlot5("");
				tradeEntity.setFromlot6("");
				tradeEntity.setFromlot7("");
				tradeEntity.setFromlot8("");
				tradeEntity.setFromlot9("");
				tradeEntity.setFromlot10("");
				tradeEntity.setFromlot11("");
				tradeEntity.setFromlot12("");
				tradeEntity.setFromlot13("");
				tradeEntity.setFromlot14("");
				tradeEntity.setFromlot15("");
				tradeEntity.setTolot1(null);
				tradeEntity.setTolot2(null);
				tradeEntity.setTolot3("");
				tradeEntity.setTolot4("");
				tradeEntity.setTolot5("");
				tradeEntity.setTolot6("");
				tradeEntity.setTolot7("");
				tradeEntity.setTolot8("");
				tradeEntity.setTolot9("");
				tradeEntity.setTolot10("");
				tradeEntity.setTolot11("");
				tradeEntity.setTolot12("");
				tradeEntity.setTolot13("");
				tradeEntity.setTolot14("");
				tradeEntity.setTolot15("");
				tradeDao.insert(tradeEntity);
			}

			// 更改当前行的状态和数量
			UpdateWrapper<RecipientsEntity> recipientsEntityUpdate = new UpdateWrapper<RecipientsEntity>();
			recipientsEntityUpdate.eq("recipientkey", recipientkey);
			RecipientsEntity recipientsEntityUpdate1 = new RecipientsEntity();
			recipientsEntityUpdate1.setStatus(RecipientConstant.RECIPIENT_STATUS_7);
			recipientsEntityUpdate1.setTray(toTray);
			recipientsEntityUpdate1.setBox(toBox);
			recipientsEntityUpdate1.setTotray(toTray);
			recipientsEntityUpdate1.setTobox(toBox);
			recipientsEntityUpdate1.setQty(qty);
			baseDao.update(recipientsEntityUpdate1, recipientsEntityUpdate);

		}
		return null;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public String backToStereo(String tray) {
		// 检查托盘是否在拣选位是否有库存
		QueryWrapper<InventoryEntity> inventoryQuery = new QueryWrapper<InventoryEntity>();
		inventoryQuery.eq("tray", tray);
		inventoryQuery.gt("qty", 0);

		List<InventoryEntity> list = inventoryDao.selectList(inventoryQuery);
		if (list.size() == 0) {
			return "箱：" + tray + "为空箱，不能回库";
		}
		for (InventoryEntity inventoryEntity : list) {
			BigDecimal pickQty = inventoryEntity.getPickqty();
			BigDecimal putQty = inventoryEntity.getPutqty();
			if (pickQty.compareTo(BigDecimal.ZERO) > 0 || putQty.compareTo(BigDecimal.ZERO) > 0) {
				return "箱：" + tray + "存在其它未完成的任务，不能回库";
			}

//			String location = inventoryEntity.getLocation();
//			if (location.equalsIgnoreCase("PICK")) {
//				return "箱："+tray+"不在拣选位，不能回库";
//			}
		}

		QueryWrapper<TaskEntity> taskQuery = new QueryWrapper<TaskEntity>();

		taskQuery.lt("status", TaskConstant.TASK_9);
		taskQuery.and(wrapper -> wrapper.eq("fromtray", tray).or().eq("totray", tray));
		Integer count = taskDao.selectCount(taskQuery);
		if (count > 0) {
			return "箱：" + tray + "存在其它未完成的任务，不能回库";
		}

		receiptdetaillistService.getPutawayTask(list.get(0),"");

		return null;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public String delivery(List<RecipientsEntity> List) {

		for (RecipientsEntity recipientsEntity : List) {

			String msg = delivery(recipientsEntity);

			if (msg != null) {
				// 回滚事务
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return msg;
			}
		}
		return null;
	}

	private String delivery(RecipientsEntity recipientsEntity) {
		// 立体库 或 需要管理唯一码的物料 必须分拣后才能发货
		QueryWrapper<RecipientsEntity> recipientsQueryCheck = new QueryWrapper<RecipientsEntity>();
		recipientsQueryCheck.eq("recipientkey", recipientsEntity.getRecipientkey());
		recipientsQueryCheck.lt("status", RecipientConstant.RECIPIENT_STATUS_7);
		recipientsQueryCheck.and(wrapper -> wrapper.exists(
				" select 1 from lswms_location where lswms_Recipients.fromloc = lswms_location.location and lswms_location.loc_category='STEREO' ")
				.or()
				.exists("  select 1 from lswms_sku where lswms_Recipients.sku =  lswms_sku.sku and lswms_sku.isuniquecode='1'"));
		Integer countCheck = baseDao.selectCount(recipientsQueryCheck);
		if (countCheck > 0) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return "需要管理唯一码或从立体库出库的物料，必须分拣后才能发货";
		}

		// 查找与订单相关的所有拣货明细
		QueryWrapper<RecipientsEntity> recipientsQuery = new QueryWrapper<RecipientsEntity>();
		recipientsQuery.eq("recipientkey", recipientsEntity.getRecipientkey());
		recipientsQuery.lt("status", 9);

		RecipientsEntity recipientsEntityIn = baseDao.selectOne(recipientsQuery);

		// 获取库存量
		QueryWrapper<InventoryEntity> inventoryQuery = new QueryWrapper<InventoryEntity>();
		inventoryQuery.eq("sku", recipientsEntityIn.getSku());
		inventoryQuery.eq("lot", recipientsEntityIn.getLot());
		inventoryQuery.eq("location", recipientsEntityIn.getLoc());
		inventoryQuery.eq("tray", recipientsEntityIn.getTray());
		inventoryQuery.eq("box", recipientsEntityIn.getBox());
		InventoryEntity inventoryEntity = inventoryDao.selectOne(inventoryQuery);
		// 校验数量
		BigDecimal recipientsQty = recipientsEntityIn.getQty();

		BigDecimal inventoryQty = BigDecimal.ZERO;
		BigDecimal inventoryPickQty = BigDecimal.ZERO;
		if (inventoryEntity != null) {
			inventoryQty = inventoryEntity.getQty();
			inventoryPickQty = inventoryEntity.getPickqty();
		}

		if (recipientsQty.compareTo(inventoryPickQty) > 0) {
			// 回滚事务
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return "库存的分配量与领用的实际量不符";
		}
		if (inventoryPickQty.compareTo(inventoryQty) > 0) {
			// 回滚事务
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return "库存的数量与分配量不符";
		}

		// 检查唯一码，如果有，则删除唯一码
		QueryWrapper<SkuEntity> skuQuery = new QueryWrapper<SkuEntity>();
		skuQuery.eq("sku", recipientsEntityIn.getSku());
		SkuEntity skuEntity = skuDao.selectOne(skuQuery);
		String isuniquecode = skuEntity.getIsuniquecode();
		if (StringUtils.isNoneBlank(isuniquecode) && isuniquecode.equals("1")) {
			QueryWrapper<UniquecodeEntity> uniquecodeQuery = new QueryWrapper<UniquecodeEntity>();
			uniquecodeQuery.eq("lot", recipientsEntityIn.getLot());
			uniquecodeQuery.eq("tray", recipientsEntityIn.getTray());
			uniquecodeQuery.eq("box", recipientsEntityIn.getBox());

			List<UniquecodeEntity> list = uniquecodeDao.selectList(uniquecodeQuery);
			if (recipientsQty.compareTo(new BigDecimal(list.size())) != 0) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return "箱：" + recipientsEntityIn.getTray() + "格：" + recipientsEntityIn.getBox() + "的发货数量与唯一码数量不相同，不能发货";
			}

			for (UniquecodeEntity uniquecodeEntity : list) {
				// 增加历史记录
				UniquecoderecordEntity uniquecoderecordEntity = new UniquecoderecordEntity();
				uniquecoderecordEntity.setUniquecode(uniquecodeEntity.getUniquecode().trim());
				uniquecoderecordEntity.setFromtray(uniquecodeEntity.getTray());
				uniquecoderecordEntity.setFrombox(uniquecodeEntity.getBox());
				uniquecoderecordEntity.setTotray(StringUtils.EMPTY);
				uniquecoderecordEntity.setTobox(StringUtils.EMPTY);
				uniquecoderecordEntity.setSku(uniquecodeEntity.getSku());
				uniquecoderecordEntity.setLot(uniquecodeEntity.getLot());
				uniquecoderecordEntity.setSourcetype("PICK");
				uniquecoderecordEntity.setSourcetable("orderdetaillist");
				uniquecoderecordEntity.setSourceid(recipientsEntityIn.getId());
				uniquecoderecordEntity.setSourcekey(recipientsEntityIn.getRecipientkey().toString());
				uniquecoderecordEntity.setSourceline(null);
				uniquecoderecordEntity.setSourcelinelist(null);
				uniquecoderecordDao.insert(uniquecoderecordEntity);

				UpdateWrapper<UniquecodeEntity> deleteWrapper = new UpdateWrapper<UniquecodeEntity>();
				deleteWrapper.eq("uniqueCode", uniquecodeEntity.getUniquecode());
				deleteWrapper.eq("lot", recipientsEntityIn.getLot());
				deleteWrapper.eq("tray", recipientsEntityIn.getTray());
				deleteWrapper.eq("box", recipientsEntityIn.getBox());
				uniquecodeDao.delete(deleteWrapper);
			}
		}

		if (inventoryEntity != null) {
			// 库存的更新数据
			InventoryEntity inventoryEntityUpdate = new InventoryEntity();
			inventoryEntityUpdate.setQty(inventoryQty.subtract(recipientsQty));
			inventoryEntityUpdate.setPickqty(inventoryPickQty.subtract(recipientsQty));
			UpdateWrapper<InventoryEntity> inventoryWrapperUpdate = new UpdateWrapper<InventoryEntity>();
			inventoryWrapperUpdate.eq("sku", inventoryEntity.getSku());
			inventoryWrapperUpdate.eq("lot", inventoryEntity.getLot());
			inventoryWrapperUpdate.eq("location", inventoryEntity.getLocation());
			inventoryWrapperUpdate.eq("tray", inventoryEntity.getTray());
			inventoryWrapperUpdate.eq("box", inventoryEntity.getBox());
			inventoryWrapperUpdate.eq("id", inventoryEntity.getId());
			inventoryDao.update(inventoryEntityUpdate, inventoryWrapperUpdate);
		}
		// 拣货记录更新
		UpdateWrapper<RecipientsEntity> recipientsWrapperUpdate = new UpdateWrapper<RecipientsEntity>();
		recipientsWrapperUpdate.eq("recipientkey", recipientsEntityIn.getRecipientkey());

		RecipientsEntity recipientsEntityUpdate = new RecipientsEntity();
		if (recipientsQty.compareTo(BigDecimal.ZERO) == 0) {
			recipientsEntityUpdate.setStatus(RecipientConstant.RECIPIENT_STATUS_18);
		} else {
			recipientsEntityUpdate.setStatus(RecipientConstant.RECIPIENT_STATUS_9);
		}
		recipientsEntityUpdate.setIssuer(SecurityUser.getUser().getUsername());
		recipientsEntityUpdate.setRecipienttime(new Date());

		baseDao.update(recipientsEntityUpdate, recipientsWrapperUpdate);

		// 增加交易记录
		// 查询批次信息
		QueryWrapper<LotEntity> lotEntityQuery = new QueryWrapper<LotEntity>();
		lotEntityQuery.eq("lot", recipientsEntityIn.getLot());
		LotEntity lotEntity = lotDao.selectOne(lotEntityQuery);

		String tradekey = sequenceService.getSequence("trade");
		TradeEntity tradeEntity = new TradeEntity();

		tradeEntity.setTradekey(tradekey);
		tradeEntity.setTradetype(TradeConstant.TRADETYPE_PICK);
		tradeEntity.setSku(recipientsEntityIn.getSku());
		tradeEntity.setQty(recipientsQty.negate());
		tradeEntity.setSourcetype("PY");
		tradeEntity.setSourcekey(recipientsEntityIn.getRecipientkey().toString());
		tradeEntity.setSourceline(null);
		tradeEntity.setSourcelinelist(null);
		tradeEntity.setFromlocation(recipientsEntityIn.getLoc());
		tradeEntity.setTolocation("");
		tradeEntity.setFromtray(recipientsEntityIn.getTray());
		tradeEntity.setTotray("");
		tradeEntity.setFrombox(recipientsEntityIn.getBox());
		tradeEntity.setTobox("");
		tradeEntity.setFromlot(recipientsEntityIn.getLot());
		tradeEntity.setTolot("");
		tradeEntity.setFromlot1(null);
		tradeEntity.setFromlot2(null);
		tradeEntity.setFromlot3("");
		tradeEntity.setFromlot4("");
		tradeEntity.setFromlot5("");
		tradeEntity.setFromlot6("");
		tradeEntity.setFromlot7("");
		tradeEntity.setFromlot8("");
		tradeEntity.setFromlot9("");
		tradeEntity.setFromlot10("");
		tradeEntity.setFromlot11("");
		tradeEntity.setFromlot12("");
		tradeEntity.setFromlot13("");
		tradeEntity.setFromlot14("");
		tradeEntity.setFromlot15("");
		tradeEntity.setTolot1(lotEntity.getLot1());
		tradeEntity.setTolot2(lotEntity.getLot2());
		tradeEntity.setTolot3(lotEntity.getLot3());
		tradeEntity.setTolot4(lotEntity.getLot4());
		tradeEntity.setTolot5(lotEntity.getLot5());
		tradeEntity.setTolot6(lotEntity.getLot6());
		tradeEntity.setTolot7(lotEntity.getLot7());
		tradeEntity.setTolot8(lotEntity.getLot8());
		tradeEntity.setTolot9(lotEntity.getLot9());
		tradeEntity.setTolot10(lotEntity.getLot10());
		tradeEntity.setTolot11(lotEntity.getLot11());
		tradeEntity.setTolot12(lotEntity.getLot12());
		tradeEntity.setTolot13(lotEntity.getLot13());
		tradeEntity.setTolot14(lotEntity.getLot14());
		tradeEntity.setTolot15(lotEntity.getLot15());
		tradeDao.insert(tradeEntity);

		return null;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public String valideAnddelete(Long[] ids) {

		// 查询信息,只有新建状态的才能删除
		QueryWrapper<RecipientsEntity> recipientsQuery = new QueryWrapper<RecipientsEntity>();
		recipientsQuery.in("id", ids);
		List<RecipientsEntity> list = baseDao.selectList(recipientsQuery);

		for (RecipientsEntity recipientsEntity : list) {
			Integer status = recipientsEntity.getStatus();
			BigDecimal qty = recipientsEntity.getQty();

			if (status != RecipientConstant.RECIPIENT_STATUS_0 && qty.compareTo(BigDecimal.ZERO) > 0) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return "不能删除非新建且数量大于0的单据";
			}
		}

		for (RecipientsEntity recipientsEntity : list) {
			BigDecimal qty = recipientsEntity.getQty();
			String lot = recipientsEntity.getLot();
			String location = recipientsEntity.getLoc();
			String tray = recipientsEntity.getTray();
			String box = recipientsEntity.getBox();
			// 撤回分配占用的库存
			if (qty.compareTo(BigDecimal.ZERO) > 0) {
				QueryWrapper<InventoryEntity> queryInventory = new QueryWrapper<InventoryEntity>();
				queryInventory.eq("lot", lot);
				queryInventory.eq("location", location);
				queryInventory.eq("tray", tray);
				queryInventory.eq("box", box);
				InventoryEntity inventoryEntity = inventoryDao.selectOne(queryInventory);
				BigDecimal pickQty = inventoryEntity.getPickqty();
				if (pickQty.compareTo(qty) < 0) {
					TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
					return "箱号：" + tray + "格号：" + box + "批号：" + lot + "的分配量不足，处理失败";
				}

				UpdateWrapper<InventoryEntity> UpdateInventory = new UpdateWrapper<InventoryEntity>();
				UpdateInventory.eq("lot", lot);
				UpdateInventory.eq("location", location);
				UpdateInventory.eq("tray", tray);
				UpdateInventory.eq("box", box);
				InventoryEntity inventoryEntityUpdate = new InventoryEntity();
				inventoryEntityUpdate.setPickqty(pickQty.subtract(qty));

				inventoryDao.update(inventoryEntityUpdate, UpdateInventory);

				baseDao.deleteById(recipientsEntity.getId());

			}
		}
		return null;
	}

	@Override
	public List<RecipientsEntity> listBySql(Map<String, Object> params) {
		List<RecipientsEntity> entityList = baseDao.selectListBySql1(getWrapper(params));
		return entityList;
	}

}